package com.webserver.http;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

/**
 * 请求对象
 * 该类每一个实例表示http协议规定的请求内容
 * 请求行，消息头，消息正文第二十一步
 */
public class HttpServletRequest {
    private static Socket socket;
    //请求行相关信息挪到类里定义成属性第二十四步
   private String method;//请求方式
   private String uri;//抽象路径
   private String protocol;//协议版本

    /*第六十四步 进一步 保存抽象路径里面信息 拆分*/
    private String requestURI;//uri中的请求部分，即？左侧内容
    private String queryString;//uri中的参数部分，即？右侧
    private Map<String,String> parameters = new HashMap<>();//每一组uri

    //消息头相关信息也定义成属性第二十五步
   private HashMap<String,String> headers =new HashMap<>();
    /**
     * 用于初始化请求对象初始化的过程
     * 就是读取浏览器发送过来的请求
     * 第二十二步
     */
    public HttpServletRequest(Socket socket) throws IOException, EmptyRequestException {
        this.socket = socket;
        //第二十九步把封装的方法在构造方法里面调1,2,3步
        //1解析请求行
        parseRaquestLine();
        //2解析消息头
        parseHeaders();
        //3解析消息正文
        parseContent();


    }
    //解析请求行第二十六步
    private void parseRaquestLine() throws IOException, EmptyRequestException {
        //解析请求
        //第十七步调读取解析的方法
        String line=readLine();
        //第六十一步如果请求行为空字符串 则本次为空请求
        if (line.isEmpty()){
            throw new EmptyRequestException();
        }
        System.out.println("请求行内容:"+line);

        //拆解请求行第十五步
        //将请求行内容按照空格拆分为三部分，分别初始化三个变量
        String[] data = line.split("\\s");
        method = data[0];
        uri = data[1];
        protocol = data[2];
        parseURI();//进一步解析uri
        System.out.println("method"+method);
        System.out.println("uri"+uri);
        System.out.println("protocol"+protocol);
    }

    /*该方法进一步解析uri抽象路径 第六十四步*/
    private void parseURI(){
    String[] data = uri.split("\\?");
    requestURI = data[0];
    if (data.length>1){
        queryString=data[1];
        //将参数部分按照”&“拆分出每一组参数
        data = queryString.split("&");
        //遍历每一组参数
        for (String para : data) {
            String[] paras =para.split("=",2);
            parameters.put(paras[0],paras[1]);
        }
    }
    }



    //解析消息头第二十七步
    private void parseHeaders() throws IOException {
        //读取消息头第十八步
        while (true) {
           String line = readLine();
            //如果读到空行说明读取消息头完毕了第十九步
            if (line.isEmpty()){
                break;
            }
            System.out.println("消息头" + line);
           String[] data = line.split(":\\s");
            //将去读到的消息头拆分存到集合里面第二十步
            headers.put(data[0],data[1]);
        }
        System.out.println("headers"+headers);
    }


    //解析消息正文第二十八步
    private void parseContent(){}


    //第十六步代码复用给读取的算法提取出来
    private String readLine() throws IOException {
        //解析请求接受进来的电话连接到输出流上第八步
        InputStream in = socket.getInputStream();
        int d;
        //为了读一行输出出来频繁拼接字符串第十一步
        StringBuilder builder =new StringBuilder();
        char pre='a',cur='a';//par表示上次读取到的一个字符，cur表示本次都得一个字符
        //第九步 读取客户端发来的信息只要读到-1表示读完了
        while ((d=in.read())!=-1){
            //将出来的信息当成字符来看第十步
            cur= (char)d;
            //判断一行是否读到了头第十二步
            if (pre==13&&cur==10){
                break;
            }
            builder.append(cur);
            //本次读到的字符赋值给上次的读到字符用来记录第十三步
            pre=cur;
        }
        //得到的一行字符去除空格才是想要得到的内容第十四步

        return builder.toString().trim();

    }

    public String getMethod() {
        return method;
    }

    public String getUri() {
        return uri;
    }

    public String getProtocol() {
        return protocol;
    }

    /**
     * 第二十五步不可以给集合全部暴露给外面改造成得到k就知道v
     * @param name
     * @return
     */
    public String getHeader(String name) {
        return headers.get(name);
    }

    public String getRequestURI() {
        return requestURI;
    }

    public String getQueryString() {
        return queryString;
    }

    public String getParameter(String name) {
        return parameters.get(name);
    }
}
